/*
 * @(#)Traceroute.java	1.0 April 30, 2008
 *
 *	The MIT License
 *
 *	Copyright (c) 2008 Malachi de AElfweald <malachid@gmail.com>
 *
 *	Permission is hereby granted, free of charge, to any person obtaining a copy
 *	of this software and associated documentation files (the "Software"), to deal
 *	in the Software without restriction, including without limitation the rights
 *	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 *	copies of the Software, and to permit persons to whom the Software is
 *	furnished to do so, subject to the following conditions:
 *
 *	The above copyright notice and this permission notice shall be included in
 *	all copies or substantial portions of the Software.
 *
 *	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 *	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 *	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 *	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 *	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 *	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 *	THE SOFTWARE.
 */
package org.eoti.net.trace;

import java.util.*;
import java.io.*;

public abstract class Traceroute
{
	public static void main(String[] args) throws IOException, InterruptedException
	{
		for(String arg : args)
		{
			System.out.format("Traceroute %s\n", arg);
			List<Hop> hops = trace(arg);
			for(Hop hop : hops)
			{
				System.out.format("\t%s\n", hop);
			}
			int totalTime = 0;
			int totalHops = 0;
			for(Hop hop : hops)
			{
				totalHops++;
				totalTime += hop.getTime();
			}
			System.out.format("%s | %d / %d ms\n", arg, totalHops, totalTime);
		}
		System.out.format("Done.\n");
	}

	public static List<Hop> trace(String destination) throws IOException, InterruptedException
	{
		String osName = System.getProperty("os.name").toLowerCase();
		if(osName.indexOf("windows") != -1)
			return (new WindowsTracert(destination)).trace();

		return (new UnixTraceroute(destination)).trace();
	}

	protected String destination;
	protected ArrayList<Hop> hops;

	protected Traceroute(String destination)
	{
		this.destination = destination;
		hops = new ArrayList<Hop>();
	}

	public List<Hop> trace() throws IOException, InterruptedException
	{
		ProcessBuilder pb = new ProcessBuilder(getCommandLine());
		pb.command().add(destination);
		Process process = pb.start();
        BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
		String line = "";
		while( (line = in.readLine()) != null)
			process(line.trim());

        int exitCode = process.waitFor();
        /* no-op w/ exitCode? */
        return hops;
	}

	protected void addHop(String num, String ipAddress, String ms1, String ms2, String ms3)
	{
		hops.add(new Hop(num, ipAddress, ms1, ms2, ms3));
	}

	protected abstract String[] getCommandLine();
	protected abstract void process(String line);
}